package com.ngovanhau.justsort;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;

import com.ngovanhau.justsort.control.ValueControl;
import com.ngovanhau.justsort.database.DatabaseHelper;
import com.ngovanhau.justsort.item.config.MyConfig;
import com.ngovanhau.justsort.model.Background;
import com.ngovanhau.justsort.model.BackgroundNumber;
import com.ngovanhau.justsort.model.Bonus;
import com.ngovanhau.justsort.model.ButtonBackGame;
import com.ngovanhau.justsort.model.Level;
import com.ngovanhau.justsort.model.LevelSetting;
import com.ngovanhau.justsort.model.LoadResourcesNumber;
import com.ngovanhau.justsort.model.Matrix2D;
import com.ngovanhau.justsort.model.MyBonus;
import com.ngovanhau.justsort.model.MyNumber;
import com.ngovanhau.justsort.model.MyText;
import com.ngovanhau.justsort.model.Star;
import com.ngovanhau.justsort.sound.MusicBackground;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;

public class MainGameActivity extends Game {

	LoadResourcesNumber loadResourcesNumber;
	public MusicBackground music;
	Background background;
	BackgroundNumber backgroundnumber;
	MySharedPreferences mySharedPreferences;
	ButtonBackGame buttonBack;
	ProgressBar progressBar;

	public Bonus bonus_items;

	public MyText text;

	public MyNumber[][] map = new MyNumber[LevelSetting.rowLevel][LevelSetting.columnLevel];

	int bonus = 0;
	int sum_bonus = 0;

	private static boolean isNumber = true;
	
	MyBonus myBonus;
	Star mStar;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		MyConfig.reSizeNumber();
		background = new Background();
		backgroundnumber = new BackgroundNumber();
		buttonBack = new ButtonBackGame();
		progressBar = new ProgressBar();
		text = new MyText();
		ValueControl.init();// init isCompleted, isTouch
		mySharedPreferences = new MySharedPreferences(this);
		loadResourcesNumber = new LoadResourcesNumber();
		bonus_items = new Bonus();
		myBonus = new MyBonus();
		mStar = new Star();
		
		music = new MusicBackground();
		music.loadMusic(this);
		music.play();
	}

	public Engine onLoadEngine() {
		super.onLoadEngine();
		return engine;
	}

	public void onLoadResources() {
		super.onLoadResources();

		background.onLoadResources(engine, context);
		backgroundnumber.onLoadResource(engine, context);
		buttonBack.onLoadResource(engine, context);
		progressBar.onLoadResources(engine, context);
		text.onLoadResources(engine, context);
		myBonus.onLoadResources(engine, context);
		mStar.onLoadResources(engine, context);
 
		if (LevelSetting.currentLevel == 6) {
			loadResourcesNumber.onLoadCharactersResources(engine, context);
			isNumber = false;
		} else {
			loadResourcesNumber.onLoadResources(engine, context);
			isNumber = true;
		}

		bonus_items.onLoadResources(engine, context);
	}

	public Scene onLoadScene() {
		super.onLoadScene();
		background.onLoadScene(scene);
		backgroundnumber.onLoadScene(scene);
		buttonBack.onLoadScene(scene);
		buttonBack.onLoadScene(scene);
		progressBar.onLoadScene(scene);
		bonus_items.onLoadScene(scene);
		text.onLoadScene(scene);
		myBonus.onLoadScene(scene);
		mStar.onLoadScene(scene);

		if (ValueControl.isMusic) {
			music.play();
		}
		Matrix2D.init();
		loadFirstItems();
		
		return this.scene;
	}

	public void resetGame() {
		resetMap();
		ValueControl.init();
		MyConfig.reSizeNumber();
		Matrix2D.resetMatrix2D();
		loadFirstItems();
		music.play();
		sum_bonus = 0;
		bonus = 0;
	}

	// load numbers item
	public void loadFirstItems() {
		int start_Y = MyConfig.Y_START;
		for (int i = 0; i < LevelSetting.rowLevel; i++) {
			int start_X = MyConfig.X_START;
			for (int j = 0; j < LevelSetting.columnLevel; j++) {
				MyNumber number = new MyNumber(this);
				number.setIJ(i, j);
				int value = Matrix2D.matrix[i][j];
				number.onLoadScene(
						scene,
						engine,
						isNumber ? loadResourcesNumber
								.getResourceName(value - 1)
								: loadResourcesNumber
										.getResourceCharactersName(value - 1),
						isNumber ? loadResourcesNumber
								.getResourceNameRed(value - 1)
								: loadResourcesNumber
										.getResourceCharactersNameRed(value - 1),
						value, start_X, start_Y);
				map[i][j] = number;
				map[i][j].moveFirst();

				start_X += MyConfig.WIDTH_NUMBER;
			}
			start_Y += MyConfig.HEIGHT_NUMBER;
		}
		showTextLevel();
	}

	public void showTextLevel() {
		Handler mHandler = new Handler();
		mHandler.postDelayed(new Runnable() {
			@Override
			public void run() {
				text.showTextLevel();
			}
		}, 2000);
	}

	// recycle bin
	public void GC() {
		try {
			System.gc();
			scene.detachChildren();
			background = null;
			backgroundnumber = null;
			buttonBack = null;
			progressBar = null;
			bonus_items = null;
			mStar = null;
			myBonus = null;
			text = null;
			map = null;
			
			Thread.sleep(20);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	public void onLoadComplete() {
		super.onLoadComplete();
	}

	// check completed level?
	public void checkLevelCompleted() {
		boolean completed = true;
		for (int i = 0; i < LevelSetting.rowLevel; i++) {
			for (int j = 0; j < LevelSetting.columnLevel; j++) {
				if (!map[i][j].checkRight())
					completed = false;
			}
		}

		if (bonus >= 2) {
			myBonus.startAnimation(bonus);
			mStar.addStar(MyConfig.SCREENWIDTH/2, MyConfig.SCREENHEIGHT/2, bonus);
			
			bonus = (int) Math.pow(2f, bonus);
			sum_bonus += bonus;
			text.subTime(bonus);
		}else if(bonus == 0){
			ValueControl.isCompletedLevel = true;
			Intent intent = new Intent(this, GameOverActivity.class);
			intent.putExtra("time", (90 + sum_bonus));
			startActivity(intent);
			finish();
			return;
		}
		
		bonus = 0;

		if (completed) {
			ValueControl.isCompletedLevel = true;
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			completedGame();
		}
	}

	public void completedGame() {
		int score = 90 + sum_bonus;
		if (score > LevelSetting.timeMinLevel) {
			Intent intent = new Intent(this, WinActivity.class);
			DatabaseHelper db = new DatabaseHelper(this);
			db.updateHighScore(new Level(LevelSetting.currentLevel,
					LevelSetting.currentType, LevelSetting.rowLevel,
					LevelSetting.columnLevel, score));
			if (LevelSetting.unlockType == LevelSetting.currentType
					&& LevelSetting.unlockType <= 25) {
				mySharedPreferences
						.updateUnlockType(LevelSetting.unlockType + 1);
			}
			intent.putExtra("time", score);
			startActivity(intent);
			finish();
		} else {
			Intent intent = new Intent(this, CompleteActivity.class);
			intent.putExtra("time", score);
			startActivity(intent);
			finish();
		}
	}

	public void addBonus() {
		bonus++;
	}

	// process game over
	public void makeTimeout() {
		// recycle bin
		ValueControl.isCompletedLevel = true;
		Intent intent = new Intent(this, GameOverActivity.class);
		intent.putExtra("time", (90 + sum_bonus));
		startActivity(intent);
		finish();
	}

	public void swapNumber(int i1, int j1, int i2, int j2) {
		MyNumber number = map[i1][j1];
		map[i1][j1] = map[i2][j2];
		map[i1][j1].setIJ(i1, j1);
		map[i2][j2] = number;
		map[i2][j2].setIJ(i2, j2);
	}

	public void resetMap() {
		synchronized (map) {
			for (int i = 0; i < LevelSetting.rowLevel; i++) {
				for (int j = 0; j < LevelSetting.columnLevel; j++) {
					MyNumber mNumber = map[i][j];
					if (mNumber != null) {
						mNumber.onDestroy();
					}
				}
			}
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		ValueControl.isCompletedLevel = true;
	}
	
	@Override
	protected void onResume(){
		super.onResume();
		music = new MusicBackground();
		music.loadMusic(this);
		music.play();
		ValueControl.isTouchNumber = true;
	}

	@Override
	protected void onStop(){
		super.onStop();
		music.pause();
		ValueControl.isTouchNumber = false;
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		ValueControl.isCompletedLevel = true;
		this.finish();
		return false;
	}

	//progressbar
	public void resetProgressBar(){
		progressBar.reload();
	}
	
	public void updateProgressBar(float value){
		progressBar.updateProgressBar(value);
	}
}